/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.search; import java.awt.*; import java.util.*; import java.text.*; import javax.swing.event.*; import org.openide.nodes.*; import org.openide.util.*; import org.openidex.search.*; import org.netbeans.modules.search.res.*; /** * Holds search result data. * * @author Petr Kuzel * @version 1.0 */ public class ResultModel implements NodeAcceptor, TaskListener { /** */ private final ChangeEvent EVENT; /** Node representing root of found nodes. * As children holds all found nodes. */ private final Node root; private SearchTask task = null; /** Search state field. */ private boolean done = false; /** search statistics field. */ private int found = 0; /** * @associates ChangeListener */ private HashSet listeners = new HashSet(); /** Which criteria produced this result. */ private CriteriaModel criteria; private boolean useDisp = false; private SearchDisplayer disp = null; /** Creates new ResultModel */ public ResultModel(CriteriaModel model) { EVENT = new ChangeEvent(this); root = new ResultRootNode(); criteria = model; } /** Some nodes was found by engine. */ public synchronized boolean acceptNodes(Node[] nodes) { root.getChildren().add(nodes); found += nodes.length; if (useDisp && disp != null) { disp.acceptNodes(nodes); } return true; } /** Whether mirror search sesults in output window. * @return new state */ synchronized boolean fillOutput (boolean fill) { if (useDisp) return true; useDisp = true; disp = new SearchDisplayer(); disp.acceptNodes(root.getChildren().getNodes()); return true; } /** Does used criteria allow filling output window? * Currently it check for presence of StructuredDetail. * @return true it it can be used. */ synchronized boolean canFillOutput() { SearchType[] crs = getCriteriaModel().getCustomizedCriteria(); for (int i=0; i < crs.length; i++) { Class[] detCls = crs[i].getDetailClasses(); //we support just AND critera relation //so if one of them support a detail then //all search results (matched nodes) will do. if (detCls == null) continue; for (int x=0; x < detCls.length; x++) { if (StructuredDetail.class == detCls[x]) return true; } } return false; } /** Is search engine still running? */ public boolean isDone() { return done; } /** */ public void setTask (SearchTask task) { this.task = task; this.task.addTaskListener(this); } /** @return root node of result */ public Node getRoot() { return root; } /** * @return criteria model that produces these results. */ public CriteriaModel getCriteriaModel() { return criteria; } /** Search task finished. Notify all listeners. */ public void taskFinished(final org.openide.util.Task task) { // set proper label of search results root node if (found==1) { root.setDisplayName ( MessageFormat.format( Res.text("MSG_FOUND_A_NODE"), // NOI18N new Object[] {new Integer(found)} ) ); } else if (found>1) { root.setDisplayName ( MessageFormat.format( Res.text("MSG_FOUND_X_NODES"), // NOI18N new Object[] {new Integer(found)} ) ); } else { // <1 root.setDisplayName(Res.text("MSG_NO_NODE_FOUND")); // NOI18N } done = true; fireChange(); } public void stop() { if (task != null) task.stop(); } public void addChangeListener(ChangeListener lis) { listeners.add(lis); } public void removeChangedListener(ChangeListener lis) { listeners.remove(lis); } /** Fire event to all listeners. */ private void fireChange() { Iterator it = listeners.iterator(); while(it.hasNext()) { ChangeListener next = (ChangeListener) it.next(); next.stateChanged(EVENT); } } /** Search Result root node. May contain some statistic properties. */ private class ResultRootNode extends AbstractNode { /** create new */ public ResultRootNode () { super(new Children.Array()); setDisplayName(Res.text("SEARCHING___")); // NOI18N } /** @return universal search icon. */ public Image getIcon(int type) { return Res.image("SEARCH"); // NOI18N } public Image getOpenedIcon(int type) { return getIcon(type); } } } /* * Log * 11 Gandalf-post-FCS1.8.2.1 4/4/00 Petr Kuzel Comments + output window * fix * 10 Gandalf-post-FCS1.8.2.0 2/24/00 Ian Formanek Post FCS changes * 9 Gandalf 1.8 1/13/00 Radko Najman I18N * 8 Gandalf 1.7 1/5/00 Petr Kuzel Margins used. Help * contexts. * 7 Gandalf 1.6 1/4/00 Petr Kuzel Bug hunting. * 6 Gandalf 1.5 12/23/99 Petr Kuzel Architecture improved. * 5 Gandalf 1.4 12/17/99 Petr Kuzel Bundling. * 4 Gandalf 1.3 12/16/99 Petr Kuzel * 3 Gandalf 1.2 12/15/99 Petr Kuzel * 2 Gandalf 1.1 12/14/99 Petr Kuzel Minor enhancements * 1 Gandalf 1.0 12/14/99 Petr Kuzel * $ */